package com.syswin.lhztest.util;


import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;

/**
 * @author:lhz
 * @date:2019/2/15 17:05
 */
public class CustomServiceLoader {

	public static final String MAPPING_CONFIG_PREFIX = "META-INF/services";

	public static <S> List<S> load(Class<S> service) {
		String mappingConfigFile = MAPPING_CONFIG_PREFIX + "/" + service.getName() ;
		//由于一个接口的实现类可能存在多个jar包中的META-INF目录下，所以下面使用getResources返回一个URL数组
		Enumeration<URL> configFileUrls = null;
		try {
			configFileUrls = CustomServiceLoader.class.getClassLoader().getResources(mappingConfigFile);
		} catch (IOException e) {
			e.printStackTrace();
		}
		if(configFileUrls == null){
			return null ;
		}
		List<S> services = new LinkedList<S>();
		while(configFileUrls.hasMoreElements()){
			URL configFileUrl = configFileUrls.nextElement();
			String configContent = null;
			try {
				configContent = StreamtoString(configFileUrl.openStream());
			} catch (IOException e) {
				e.printStackTrace();
			}
			String[] serviceNames = configContent.split("\n");
			for(String serviceName : serviceNames){
				Class serviceClass = null;
				try {
					serviceClass = CustomServiceLoader.class.getClassLoader().loadClass(serviceName);
				} catch (ClassNotFoundException e) {
					e.printStackTrace();
				}
				Object serviceInstance = null;
				try {
					serviceInstance = serviceClass.newInstance();
				} catch (InstantiationException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				}
				services.add((S)serviceInstance);
			}
		}
		return services ;
	}

	private static String StreamtoString(InputStream inputStream){
		byte[] bytes = null;
		try {
			bytes = new byte[inputStream.available()];
		} catch (IOException e) {
			e.printStackTrace();
		}
		try {
			inputStream.read(bytes);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return new String(bytes);
	}
}
